//
//  TaskAiDiaryExt.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/3/19.
//

import Foundation
import Foundation
import SwiftUI
//ai日记任务创建
class TaskAiDiaryExt : BaseViewModel {
    static let instance = TaskAiDiaryExt()

    private var mapDelay : [String?:Bool] = [:]
    private let modeType = IAiModelType.aiDiary.rawValue
    private let mapQueue = DispatchQueue(label: "mapDelayQueue")
    private let tag = "checkAiDiary"

    func getMapValue(_ key: String) -> Bool {
        return mapQueue.sync {
            self.mapDelay[key] ?? false
        }
    }
    
    func putMapValue(_ key: String,_ bool: Bool) {
        return mapQueue.sync {
            self.mapDelay[key] = bool
        }
    }
    
    func removeMapValue(_ key: String) {
        return mapQueue.sync {
            self.mapDelay.removeValue(forKey: key)
        }
    }
    
    func doCheck() {
        request(isLoading: false,timeout: 60 * 60) {
            showLog(self.tag,"开始检查AI 日记")
            try check(self.tag, !isExamine()) {
                "审核版本，不开启功能"
            }
            try check(self.tag, AppStorageManager.shared.toggleAi) {
                "AI 功能已关闭"
            }
            try check(self.tag, AppStorageManager.shared.toggleAiDiary) {
                "AI 日记功能已关闭"
            }
            try check(self.tag, userManager.isVip()) {
                "该功能是Pro用户专享"
            }
            try check(self.tag, AiChatExt.isAiEnabled() || AiCustomUtils.shared.isCustomAi(type: self.modeType)) {
                "AI 功能已用尽,请前往活动领取次数"
            }
            try check(self.tag, !userManager.getUserId().isEmpty) {
                "用户不为空"
            }
            let listTaskBean = try await BackupsManager.shared.getDelegateDiary()?.getLatelyTask(roleId: nil, userId: userManager.getUserId(), type: ITaskType.AI_DIARY.rawValue, pageSize: 15) ?? []//15条，大概就是5个人，平均3天
            try check(self.tag, listTaskBean.isEmpty == false) {
                "ai日记任务为空"
            }
            return listTaskBean
        }  suc: { (listTaskBean : [TaskBean]) in
            for task in listTaskBean {
                self.doTask(task)
            }
        } fail: { _ in
            
        }
    }
    
    func doTask(_ taskBean: TaskBean,
                _ backup: Bool = false) {
        var errorApi = ""
        request(isLoading: false,timeout: 60 * 60) {
            let exit = self.getMapValue(taskBean.objectId ?? "")
            try check(self.tag, exit == false) {
                "正在检查该ai任务"
            }
            self.putMapValue(taskBean.objectId ?? "", true)
            let aiRole = try await BackupsManager.shared.getDelegateConfig()?.getAiRole(roleId: taskBean.roleId)
            let aiNotEmpty  = aiRole?.objectId?.isEmpty == false
            try check(self.tag, aiNotEmpty) {
                "ai角色已删除"
            }
            showLog(self.tag, "\(String(describing: aiRole?.name))日记任务格式\(String(describing: toJson(taskBean)))")
            //查询他的前5条日记
            let list = try await BackupsManager.shared.getDelegateDiary()?.queryDiaryAi(userId: userManager.getUserId(), roleId:  aiRole?.objectId ?? "", keyword: nil, pageNo: 0, pageSize: 5) ?? []
            let aiModel: Int  = configManager.getConfig().aiChat.getAiModel(aiMode: IAiModelType.aiDiary)
            var replyStr : String = ""
            
            if backup {
                //启动备用方案
                try await retry(maxRetries: 3, retryDelayMillis: 500) {
                    let aiModeBean = configManager.getConfig().getAiChatMode2(key: self.modeType)
                    errorApi = "\(aiModeBean.host ?? ""),\(aiModeBean.model ?? "")"
                    let bean = AIDiaryBean(model : aiModeBean.model, list: list, time: getSecond(time: TimeInterval(taskBean.time)), botRoleBean: RoleBean.get(aiRole!))
                    showLog(self.tag, "请求ai日记：\(String(describing: toJson(bean)))")
                    let result = try await AiNetManager.shared.requestAI(host: aiModeBean.host, token: aiModeBean.token, jsonObject: toJson(bean), modeType: AIChatResultBean.self)
                    replyStr = result.getReplyStr()
                }
            } else if AiCustomUtils.shared.isCustomAi(type: self.modeType) {
                //自定义
                try await retry(maxRetries: 3, retryDelayMillis: 500) {
                    let host = AiCustomUtils.shared.getCustomHost(type: self.modeType)
                    let token = AiCustomUtils.shared.getCustomToken(type: self.modeType)
                    let model = AiCustomUtils.shared.getCustomModel(type: self.modeType)
                    errorApi = "\(host),\(model)"
                    let bean = AIDiaryBean(model : model, list: list, time: getSecond(time: TimeInterval(taskBean.time)), botRoleBean: RoleBean.get(aiRole!))
                    showLog(self.tag, "请求ai日记：\(String(describing: toJson(bean)))")
                    let result = try await AiNetManager.shared.requestAI(host: host, token: token, jsonObject: toJson(bean), modeType: AIChatResultBean.self)
                    replyStr = result.getReplyStr()
                }
            } else {
                switch aiModel {
                case 1,2:
                    //配置模型
                    try await retry(maxRetries: 1, retryDelayMillis: 500) {
                        let aiModeBean = configManager.getConfig().getAiChatMode(key: self.modeType)
                        errorApi = "\(aiModeBean.host ?? ""),\(aiModeBean.model ?? "")"
                        let bean = AIDiaryBean(model : aiModeBean.model, list: list, time: getSecond(time: TimeInterval(taskBean.time)), botRoleBean: RoleBean.get(aiRole!))
                        showLog(self.tag, "请求ai日记：\(String(describing: toJson(bean)))")
                        let result = try await AiNetManager.shared.requestAI(host: aiModeBean.host, token: aiModeBean.token, jsonObject: toJson(bean), modeType: AIChatResultBean.self)
                        replyStr = result.getReplyStr()
                    }
                default:
                    try await retry(maxRetries: 3, retryDelayMillis: 500) {
                        let bean = AIDiaryMinmaxBean(list: list, time: getSecond(time: TimeInterval(taskBean.time)), botRoleBean: RoleBean.get(aiRole!))
                        showLog(self.tag, "请求ai日记：\(String(describing: toJson(bean)))")
                        let result = try await AiNetManager.shared.requestAIMinMax(jsonObject: toJson(bean), modeType: AIChatResultMinmaxBean.self)
                        replyStr = result.getReplyStr(true)
                    }
                }
            }
            showLog(self.tag, "请求ai日记")
            showLog(self.tag, replyStr)
            try check(self.tag, !isAiReplyProhibit(replyStr), "AI含有违禁词")
            //日记写入数据库
            let diaryBean = DiaryBean(content: replyStr)
            diaryBean.time = taskBean.time
            diaryBean.roleId = aiRole?.objectId
            diaryBean.roleType = IRoleType.BOT.rawValue
            //写入数据库
            try await retry(maxRetries: 10, retryDelayMillis: 500) {
                try await BackupsManager.shared.getDelegateDiary()?.saveDiary(bean: diaryBean)
            }
            //任务结束
            try await retry(maxRetries: 10, retryDelayMillis: 500) {
                taskBean.execute = true
                _ = try await BackupsManager.shared.getDelegateDiary()?.saveTask(bean: taskBean)
            }
            return aiRole!
        }  suc: { (aiRole : AiRoleBean) in
            self.removeMapValue(taskBean.objectId ?? "")
            if !AiCustomUtils.shared.isCustomAi(type: self.modeType) {
                AiChatExt.deductAiChatCountCommon()
            }
            //发送通知刷新界面
            NotificationCenter.default.post(name: .aiDiary, object: aiRole.objectId) //发送事件
        } fail: { it in
            self.removeMapValue(taskBean.objectId ?? "")
            if ERROR.NET_ERRPR.rawValue == it.code {
                AiChatExt.reportError(
                    type: self.modeType,
                    typeName: "ai日记",
                    message: it.realMessage,
                    errorApi: errorApi)
                
                if let error = configManager.getConfig().getAiError(content: it.realMessage) {
                    showToast(error)
                }
            } else {
                //非自定义使用备用方案
                if !backup && !AiCustomUtils.shared.isCustomAi(type: self.modeType) {
                    showLog(self.tag, "ai日记使用备用方案")
                    self.doTask(taskBean,true)
                }
            }
        }
    }
    
    
    func doCreate() {
        request(isLoading: false,timeout: 60 * 60) {
            try check(self.tag, !isExamine()) {
                "审核版本，不开启功能"
            }
            let curTime = try await getNetTime()
            let listRole = try await BackupsManager.shared.getDelegateConfig()?.getSelectAiRoleList().prefix(5)
            //循环创建5个任务
            for aiRole in listRole ?? [] {
                try await self.create(curTime, aiRole)//今天任务
                //系统的不创建明天任务
                if (aiRole.isSystem == false) {
                    try await self.create(self.getTomorrowAt6AM(time: curTime), aiRole)
                }
            }
        } suc: { list in
            
        } fail: { _ in
            
        }
    }
    
    func create(_ time: TimeInterval, _ aiRole: AiRoleBean?)  async throws {
        do {
            showLog(self.tag, "开始创建AI日记任务")
            try check(self.tag,aiRole != nil){
                "AI 为空"
            }
            try check(self.tag,userManager.isVip()) {
                "该功能是Pro用户专享"
            }
            try check(self.tag,AppStorageManager.shared.toggleAi) {
                "AI 功能已关闭"
            }
            try check(self.tag,AppStorageManager.shared.toggleAiDiary) {
                "AI 日记功能已关闭"
            }
            try check(self.tag,AiChatExt.isAiEnabled() || AiCustomUtils.shared.isCustomAi(type: self.modeType)) {
                "AI 功能已用尽,请前往活动领取次数"
            }
            //随机时间
            
            let timeKey: String = TimeUtils.getDate(time: time, format: "yyyy-MM-dd")
            let exist = try await BackupsManager.shared.getDelegateDiary()?.existTask(
                timeKey: timeKey, roleId: aiRole?.objectId, userId: userManager.getUserId(), type: ITaskType.AI_DIARY.rawValue
            )
            try check(self.tag,exist == false) {
                "\(timeKey)AI日记任务已经存在"
            }
            let taskName = "ai日记"
            let taskBean = TaskBean()
            //随机当前时间到23点59
            let time: Int64 = getMillisecond(TaskExt.randomTime(time))
            taskBean.time = time
            taskBean.name = taskName
            taskBean.timeKey = timeKey
            taskBean.roleId = aiRole?.objectId ?? nil
            taskBean.userId = userManager.getUserId()
            taskBean.type = ITaskType.AI_DIARY.rawValue
            let task = try await BackupsManager.shared.getDelegateDiary()?.saveTask(bean: taskBean)
            let msgId = task?.objectId ?? ""
            try check(self.tag,msgId.isEmpty == false) {
                "AI日记消息id为空"
            }
            showLog(self.tag,"创建AI日记任务\(String(describing: msgId))")
            showLog(self.tag,"创建AI日记任务\(TimeUtils.getDate(time: time, format: "yyyy-MM-dd HH:mm:ss"))")
            //开始请求推送
            //开始设置定时推送,需要后台开关配置 或者vip
            if (configManager.getConfig().getSwitchConfig().isPushTask() && configManager.getConfig().getSwitchConfig().isPushAiDiary2) {
                showLog(self.tag,"开始创建AI日记推送任务")
                try await retry(maxRetries: 5, retryDelayMillis: 1000) {
                    try await PushExt.sendSchedule(taskName: taskName, msgId: msgId, title: aiRole?.name ?? "", content: "写了一篇日记", time: time)
                }
            }
        } catch {
            showLog(self.tag,"创建AI日记失败：\(error)")
        }
    }
    
    //明天6点，单位秒
    func getTomorrowAt6AM(time: TimeInterval) -> TimeInterval {
        let date = Date(timeIntervalSince1970: getSecond(time: time))
        let calendar = Calendar.current
        
        // 增加一天
        guard let tomorrow = calendar.date(byAdding: .day, value: 1, to: date) else {
            return 0
        }
        
        // 设置时间为 6:00:00
        guard let tomorrowAt6AM = calendar.date(bySettingHour: 6, minute: 0, second: 0, of: tomorrow) else {
            return 0
        }
        
        // 转换为毫秒时间戳
        return tomorrowAt6AM.timeIntervalSince1970
    }
    
    /**
     * 更新ai日记任务
     */
    func updateTask() {
        Task {
            let listTaskBean = try await BackupsManager.shared.getDelegateDiary()?.getUnExecutedTask(roleId: nil, userId: userManager.getUserId(), type: ITaskType.AI_DIARY.rawValue) ?? []
            showLog(self.tag, "开始删除日记任务数量:\(listTaskBean.count)")
            for task in listTaskBean {
                showLog(self.tag, "开始删除日记任务:\(String(describing: task.objectId))")
                try await BackupsManager.shared.getDelegateDiary()?.deleteTask(bean: task)
            }
            await MainActor.run {
                //旧任务删除成功后，开始创建新的
                doCreate()
            }
        }
    }
}
